#pragma once
#define QUAT_EPSILON 0.000001f
#define QUAT_DEG2RAD 0.0174533f
#define QUAT_RAD2DEG 57.2958f

#include "Vec3.h"
#include "Mat4.h"

struct Quat {
	union {
		struct {
			float x;
			float y;
			float z;
			float w;
		};
		struct {
			Vec3 vector;
			float scalar;
		};
		float v[4];
	};

	inline Quat() : x(0), y(0), z(0), w(1) { }

	inline Quat(float _x, float _y, float _z, float _w) :
		x(_x), y(_y), z(_z), w(_w) {}
};

Quat AngleAxis(float angle, const Vec3& axis);
Quat FromTo(const Vec3& from, const Vec3& to);
Vec3 GetAxis(const Quat& Quat);
float GetAngle(const Quat& Quat);
Quat operator+(const Quat& a, const Quat& b);
Quat operator-(const Quat& a, const Quat& b);
Quat operator*(const Quat& a, float b);
Quat operator-(const Quat& q);
bool operator==(const Quat& left, const Quat& right);
bool operator!=(const Quat& a, const Quat& b);
bool SameOrientation(const Quat& left, const Quat& right);
float Dot(const Quat& a, const Quat& b);
float LenSq(const Quat& q);
float Len(const Quat& q);
void Normalize(Quat& q);
Quat Normalized(const Quat& q);
Quat Conjugate(const Quat& q);
Quat Inverse(const Quat& q);
Quat operator*(const Quat& Q1, const Quat& Q2);
Vec3 operator*(const Quat& q, const Vec3& v);
Quat Mix(const Quat& from, const Quat& to, float t);
Quat Nlerp(const Quat& from, const Quat& to, float t);
Quat operator^(const Quat& q, float f);
Quat operator^(const Quat& q, float f);
Quat Slerp(const Quat& start, const Quat& end, float t);
Quat LookRotation(const Vec3& direcion, const Vec3& up);
Mat4 QuatToMat4(const Quat& q);
Quat Mat4ToQuat(const Mat4& m);
